package com.api.weavernorth.modling;

import com.alibaba.fastjson.JSONObject;
import com.weavernorth.modelInterFace.pojo.*;
import com.weavernorth.modelInterFace.service.modeDaoImpl;
import com.weavernorth.util.Logger4jUtil;
import org.apache.log4j.Logger;
import weaver.conn.ConnStatement;
import weaver.conn.ConnectionPool;
import weaver.conn.RecordSet;
import weaver.general.Util;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author: bruseewang
 * @Package: com.api.weavernorth.modling
 * @date: 2020/6/29 11:07
 * @description: 外部系统操作OA建模表通用接口
 */
@Path("/Models")
public class OperationData extends HttpServlet {
    private static ConnectionPool pool = ConnectionPool.getInstance();
    private Connection conn;
    private Statement statement;
    private ConnStatement rs_main_tb;
    private ConnStatement rs_detail_tb;
    private Lock lock = new ReentrantLock();
    private Logger log = Logger4jUtil.getLoggerByName("/action/api/OperationData/");
    Map<String,String> mp_main=new HashMap<>();
    Map<String,String> mp_detail=new HashMap<>();
    Map<String,String> mp_main_sql=new HashMap<>();
    Map<String,String> mp_detail_sql=new HashMap<>();
    modeDaoImpl dao = new modeDaoImpl();
    @POST
    @Path("/changeModel")
    @Produces(MediaType.APPLICATION_JSON)
    public String operationModel(@Context HttpServletRequest httpservletrequest, @Context HttpServletResponse httpservletresponse, JSONObject jsonObject) throws SQLException {
        log.info("统一建模接口调用开始：");
        //返回json
        JSONObject jsonReturn = new JSONObject();
        Boolean flag = true;
        lock.lock();//获取锁,如果锁被暂用则一直等待
        //外部系统传入的参数
        log.info("外部系统传入的数据:" + jsonObject.toString());
        log.info("传入数据的长度为："+jsonObject.toString().length());
        try {
            //1.将请求结构体转换为对象
            //region[弃用]
//            Map<String, Class<?>> classMap = new HashMap<String, Class<?>>();
//            classMap.put("main_list", mainVo.class);
//            classMap.put("detail_list", detailVo.class);
//            classMap.put("data", filedEntity.class);
//            requestDataVo dataVo = (requestDataVo) JSONObject.toBean(jsonObject, requestDataVo.class, classMap);
            //endregion
            requestDataVo dataVo=JSONObject.toJavaObject(jsonObject, requestDataVo.class);
            //外围系统名称
            String strSysName = dataVo.getSysName();
            log.info("外围系统名称："+strSysName);
            //外围系统表名
            String strSysTable = dataVo.getSysTable();
            log.info("外围系统表名："+strSysTable);
            //用户名
            String struserName = dataVo.getUserName();
            log.info("用户名："+struserName);
            //密码
            String strpassWorld = dataVo.getPassWord();
            //获取主表主键,如果主键为空,则只对主表操作,否则对主表及明细表都操作
            String strmainKey = dataVo.getMainKey();
            //明细表编号(代表是哪个明细表)
            //数据库
            String strdataBase = dataVo.getDataBase();
            //是否删除
            String strIsDel = dataVo.getIsDel();
            //主表
            List<mainVo> data_list = dataVo.getMain_list();
//            log.info("json转集合主表对象"+data_list);
            List<detailVo> detail_list = dataVo.getDetail_list();
//            log.info("json转集合明细表对象"+detail_list);
            int list_Count = 0;

            //获取主表表对象集合
            //2.查询权限表:uf_jmqx
            String strSql = "select * from uf_jmqx where wwxt='" + strSysName + "' and wwbm ='" + strSysTable + "' and yhm='" + struserName + "' and mm='" + strpassWorld + "'";
            RecordSet rs = new RecordSet();
            rs.executeQuery(strSql);
            Integer rowsALl = rs.getCounts();
            String strOaTable = "";
            String strCheckBrowser="0";//是否判断浏览按钮,如果为0，则不判断
            //批量操作
            conn=pool.getConnection();
            statement=conn.createStatement();
            if (rowsALl > 0) {
                while (rs.next()) {
                    //3.权限通过,查找要更新的OA系统的表
                    strOaTable = Util.null2String(rs.getString("oabm"));
                    strCheckBrowser= Util.null2String(rs.getString("sfymscszdyllan"));
                }
                if (!"".equals(strOaTable)) {
                    list_Count = data_list.size();
                    log.info("主表集合总数：" + list_Count);
                    if (list_Count > 0) {
                        if (!strIsDel.equals("Y")) {
                            //操作主表
                            if (data_list.size()>0) {
                                log.info("对主表操作开始。。。");
                                Long begin = new Date().getTime();
                                messageVo messageVo=null;

                                //region[获取表列名]
                                String strSql1 = "select * from "+ strOaTable + " where ROWNUM=1";
                                rs_main_tb = new ConnStatement();
                                rs_main_tb.setStatementSql(strSql1);
                                rs_main_tb.executeQuery();
                                String columnNames = dao.getColumnNames(rs_main_tb);
                                rs_main_tb.close();
                                //endregion

                                for (mainVo mainVo : data_list) {
                                    //只要有一个错误就不再继续
                                    if (flag) {
                                        //主键
                                        String strTbkey = mainVo.getTbKey();
                                        List<filedEntity> data = mainVo.getData();
                                        int dataSize = data.size();
                                        if (dataSize > 0) {
                                            log.info("main的集合数据：" + data.toString());
                                            String strMainSql = "select * from " + strOaTable + " where mainKey='" + strTbkey + "'";
                                            log.info("查询主表sql:" + strMainSql);
                                                rs_main_tb = new ConnStatement();
                                                rs_main_tb.setStatementSql(strMainSql);
                                                rs_main_tb.executeQuery();
                                                if (rs_main_tb.next()) {
                                                    log.info("主表-更新数据开始：");
                                                        mp_main_sql.clear();
                                                        messageVo=null;
                                                        Long begin1 = new Date().getTime();
                                                        messageVo = dao.check_Data(data, columnNames,rs_main_tb, strCheckBrowser, mp_main, strOaTable, mp_main_sql,"update");
                                                        Long end1 = new Date().getTime();
                                                        log.info("主表更新-校验数据耗时："+(end1 - begin1)+"(毫秒)");
                                                        if(mp_main_sql.keySet().size()>0 && messageVo.getStatus().equals("0")) {
                                                            String update_rs = dao.update_main_new(strOaTable, strTbkey, mp_main, mp_main_sql);
                                                            log.info("更新主表数据返回结果：" + update_rs);
                                                            if(!"".equals(update_rs)){
                                                                //填装更新sql语句
                                                                statement.addBatch(update_rs);
                                                            }else{
                                                                jsonReturn.put("status", "F");
                                                                jsonReturn.put("message", "更新主表数据异常,请查看日志");
                                                                flag = false;
                                                                break;
                                                            }

                                                        }else{
                                                            jsonReturn.put("status", "F");
                                                            jsonReturn.put("message", messageVo.getMessage());
                                                            flag = false;
                                                            break;
                                                        }

                                                } else {
                                                    //不存在则新增
                                                    log.info("插入数据开始：");
                                                        mp_main_sql.clear();
                                                        messageVo=null;
                                                        Long begin1 = new Date().getTime();
                                                        messageVo = dao.check_Data(data,columnNames, rs_main_tb, strCheckBrowser, mp_main, strOaTable, mp_main_sql,"insert");
                                                        Long end1 = new Date().getTime();
                                                        log.info("主表新增-校验数据耗时："+(end1 - begin1)+"(毫秒)");
                                                        if(messageVo.getStatus().equals("0")&&mp_main_sql.keySet().size()>0) {
//                                                            String insert_rs = dao.insertData(strOaTable, data, strTbkey, rs_main_tb, strCheckBrowser, mp_main);
                                                            String insert_rs = dao.insert_main_new(strOaTable, strTbkey, mp_main,mp_main_sql);
                                                            log.info("更新主表数据返回结果：" + insert_rs);
                                                            if(!"".equals(insert_rs)){
                                                                //填装更新sql语句
                                                                statement.addBatch(insert_rs);
                                                            }else{
                                                                jsonReturn.put("status", "F");
                                                                jsonReturn.put("message", "新增主表数据异常,请查看日志");
                                                                flag = false;
                                                                break;
                                                            }
                                                        }else{
                                                            jsonReturn.put("status", "F");
                                                            jsonReturn.put("message", messageVo.getMessage());
                                                            flag = false;
                                                            break;
                                                        }

                                                }
                                                try {
                                                    rs_main_tb.close();
                                                }catch (Exception ex){
                                                    log.info("查询主表数据时,关闭数据库连接异常,异常信息："+ex.toString());
                                                    jsonReturn.put("status", "F");
                                                    jsonReturn.put("message", "查询主表数据时,关闭数据库连接异常,异常信息："+ex.toString());
                                                    flag = false;
                                                    break;
                                                }
                                        }
                                    }
                                }
                                //执行批处理
                                Long begin1 = new Date().getTime();
                                statement.executeBatch();
                                Long end1 = new Date().getTime();
                                log.info("主表-批量更新耗时："+(end1 - begin1)+"(毫秒)");
                                Long end = new Date().getTime();
                                log.info("循环总耗时："+(end - begin)+"(毫秒)");
                                log.info("对主表操作结束。。。。");
                            }
                            if (!"".equals(strmainKey)) {//操作明细表
                                if (detail_list.size() > 0) {
                                    log.info("明细表集合总数："+detail_list.size());
                                    log.info("对明细表操作开始。。。。");
                                    messageVo messageVo=null;
                                    String strSql2 = "select * from "+ strOaTable + "_dt where ROWNUM=1";
                                    rs_detail_tb = new ConnStatement();
                                    rs_detail_tb.setStatementSql(strSql2);
                                    rs_detail_tb.executeQuery();
                                    String columnNames2 = dao.getColumnNames(rs_detail_tb);
                                    rs_detail_tb.close();
                                    for (detailVo detailVo : detail_list) {
                                        if (flag) {
                                            //明细表编号(第几个明细表)
                                            String strDetailNo = detailVo.getDetailNo();
                                            //明细表表名
                                            String strTb_detail = strOaTable + "_dt" + strDetailNo;
                                            //明细表主键
                                            String strTbkey = detailVo.getTbKey();
                                            List<filedEntity> data_detail = detailVo.getData();
                                            int dataSize = data_detail.size();
                                            if (dataSize > 0) {
                                                log.info("detail的集合数据：" + data_detail.toString());
                                                String strDetailSql = "select * from " + strTb_detail + " where mainKey='" + strmainKey + "' and tbKey='" + strTbkey + "'";
                                                log.info("查询明细表sql:" + strDetailSql);
                                                try {
                                                    rs_detail_tb=new ConnStatement();
                                                    rs_detail_tb.setStatementSql(strDetailSql);
                                                    rs_detail_tb.executeQuery();
                                                    if (rs_detail_tb.next()) {
                                                        log.info("更新数据开始：");
                                                        mp_detail_sql.clear();
                                                        messageVo=null;
                                                        messageVo = dao.check_Data(data_detail,columnNames2, rs_main_tb, strCheckBrowser, mp_detail, strOaTable, mp_detail_sql,"update");
//
                                                        if(messageVo.getStatus().equals("0") && mp_detail_sql.keySet().size()>0) {
                                                            //调用更新数据方法
//                                                        String update_rs = dao.update_detail(strTb_detail, data_detail, strTbkey, strmainKey, rs_detail_tb,strCheckBrowser,mp_detail);
                                                            String update_rs = dao.update_detail_new(strTb_detail, strTbkey, strmainKey, mp_detail,mp_detail_sql);
                                                            log.info("更新明细表数据返回结果：" + update_rs);
                                                           if(!"".equals(update_rs)){
                                                               statement.addBatch(update_rs);
                                                           }else{
                                                               jsonReturn.put("status", "F");
                                                               jsonReturn.put("message", "更新明细表数据异常,请查看日志");
                                                               flag = false;
                                                               break;
                                                           }
                                                        }else{
                                                            jsonReturn.put("status", "F");
                                                            jsonReturn.put("message", messageVo.getMessage());
                                                            flag = false;
                                                            break;
                                                        }
                                                    } else {
                                                        //不存在则新增
                                                        log.info("插入数据开始：");
                                                        mp_detail_sql.clear();
                                                        messageVo=null;
                                                        messageVo = dao.check_Data(data_detail, columnNames2,rs_main_tb, strCheckBrowser, mp_detail, strOaTable, mp_detail_sql,"insert");
//                                                        log.info("新方法-返回对象的值："+messageVo.toString());
//                                                        log.info("新方法-对应的sql1:"+mp_sql.get("strNameSql"));
//                                                        log.info("新方法-对应的sql2:"+mp_sql.get("strValSql"));
                                                        if(messageVo.getStatus().equals("0") && mp_detail_sql.keySet().size()>0) {
                                                            String insert_rs = dao.insert_detail(strTb_detail, data_detail, strTbkey, strmainKey, rs_detail_tb, strCheckBrowser, mp_detail);
                                                            log.info("插入明细表数据返回结果：" + insert_rs);
                                                            if(!"".equals(insert_rs)){
                                                                //填装更新sql语句
                                                                statement.addBatch(insert_rs);
                                                            }else{
                                                                jsonReturn.put("status", "F");
                                                                jsonReturn.put("message", "新增主表数据异常,请查看日志");
                                                                flag = false;
                                                                break;
                                                            }
                                                        }else{
                                                            jsonReturn.put("status", "F");
                                                            jsonReturn.put("message", messageVo.getMessage());
                                                            flag = false;
                                                            break;
                                                        }
                                                    }
                                                } catch (Exception ex) {
                                                    log.info("查询数据出现异常：" + ex.toString());
                                                    jsonReturn.put("status", "F");
                                                    jsonReturn.put("message", "出现异常：" + ex.toString());
                                                    flag = false;
                                                    break;
                                                }
                                            }

                                        }
                                    }
                                    log.info("对明细表操作结束。。。。");
                                }else{
                                    flag = false;
                                    log.info("明细表数据为空！");
                                    jsonReturn.put("status", "F");
                                    jsonReturn.put("message", "明细表数据为空!");
                                }
                            }
                        } else {
                            log.info("删除操作");
                            String strTbKey = "";//主键
                            String strTbName = "";//表名
                            String strKey_m = "";//更新明细表时主表主键
                            if (data_list.size()>0) {
                                for (mainVo mainVo : data_list) {
                                    String strMain=mainVo.getTbKey();
                                    //执行删除操作
                                    log.info("要删除的主表表名：" + strTbName + ";要删除的数据主键：" + strMain);
                                    String strDelResult = dao.delete_Data(strTbName, strMain, strmainKey);
                                    String strCode = strDelResult.substring(0, strDelResult.indexOf("|"));
                                    String msg_up = strDelResult.substring(strDelResult.indexOf("|") + 1, strDelResult.length());
                                    if (!"0".equals(strCode)) {
                                        flag = false;
                                        jsonReturn.put("status", "F");
                                        jsonReturn.put("message", msg_up);
                                        break;
                                    }
                                }
                            }
                            if (data_list.size()>0&&!"".equals(strmainKey)) {
                                strKey_m=strmainKey;
                                //删除明细表数据
                                for (detailVo detailVo : detail_list) {
                                    //主键
                                    strTbKey = detailVo.getTbKey();
                                    strTbName = strOaTable + "_dt" + detailVo.getDetailNo();//获取明细表表名
                                    if (!"".equals(strTbKey)&&!"".equals(strTbName)) {
                                        //执行删除操作
                                        log.info("要删除的明细表表名：" + strTbName + ";要删除的数据主键：" + strTbKey);
                                        String strDelResult = dao.delete_Data(strTbName, strTbKey, strKey_m);
                                        String strCode = strDelResult.substring(0, strDelResult.indexOf("|"));
                                        String msg_up = strDelResult.substring(strDelResult.indexOf("|") + 1, strDelResult.length());
                                        if (!"0".equals(strCode)) {
                                            flag = false;
                                            jsonReturn.put("status", "F");
                                            jsonReturn.put("message", msg_up);
                                            break;
                                        }
                                    }
                                }
                            } else {
                                flag = false;
                                jsonReturn.put("status", "F");
                                jsonReturn.put("message", "没有可删除的数据!");
                            }
                        }
                    } else {
                        flag = false;
                        log.info("接口main_list为空！");
                        jsonReturn.put("status", "F");
                        jsonReturn.put("message", "接口传输数据为空!");
                    }
                } else {
                    flag = false;
                    log.info("该表在OA中没有权限,请联系管理员！");
                    jsonReturn.put("status", "F");
                    jsonReturn.put("message", "该表在OA中没有权限,请联系管理员!");
                }


            } else {
                flag = false;
                log.info("接口数据中的建模表没有操作权限,请联系管理员！");
                jsonReturn.put("status", "F");
                jsonReturn.put("message", "接口数据中的建模表没有操作权限,请联系管理员！");
            }
        } catch (Exception ex) {
            flag = false;
            ex.printStackTrace();
            log.info("数据传输错误：" + ex.toString());
            jsonReturn.put("status", "F");
            jsonReturn.put("message", "数据传输错误：" + ex.toString());
        } finally {
            conn.close();
            statement.close();
            if (flag) {
                jsonReturn.put("status", "S");
                jsonReturn.put("message", "操作成功！");
            }
            lock.unlock();
        }
        messageVo mess=new messageVo();
        mess.setStatus(jsonReturn.get("status").toString());
        mess.setStatus(jsonReturn.get("message").toString());
        return jsonReturn.toString();
    }
}
